﻿using LdtJudge.DataEngine.Model.XMLConfigModel.DataStores;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Xml;
using System.Xml.Serialization;

namespace LdtJudge.DataEngine.Common.XmlUtility
{
    /// <summary>
    /// xml帮主类
    /// </summary>
    public class XmlUtility
    {

        /// <summary>
        /// 将自定义对象序列化为XML字符串
        /// </summary>
        /// <param name="myObject">自定义对象实体</param>
        /// <returns>序列化后的XML字符串</returns>
        public static string SerializeToXml<T>(T myObject)
        {
            if (myObject != null)
            {
                XmlSerializer xs = new XmlSerializer(typeof(T));

                MemoryStream stream = new MemoryStream();
                XmlTextWriter writer = new XmlTextWriter(stream, Encoding.UTF8);
                writer.Formatting = Formatting.None;//缩进
                xs.Serialize(writer, myObject);

                stream.Position = 0;
                StringBuilder sb = new StringBuilder();
                using (StreamReader reader = new StreamReader(stream, Encoding.UTF8))
                {
                    string line;
                    while ((line = reader.ReadLine()) != null)
                    {
                        sb.Append(line);
                    }
                    reader.Close();
                }
                writer.Close();
                return sb.ToString();
            }
            return string.Empty;
        }
       

        public static string SerializeToXmlNew<T>(T myObject)
        {

            System.Xml.Serialization.XmlSerializer xs = new System.Xml.Serialization.XmlSerializer(typeof(T));
            System.Xml.Serialization.XmlSerializerNamespaces ns = new System.Xml.Serialization.XmlSerializerNamespaces();
            ns.Add("", "");
            System.IO.MemoryStream stream = new System.IO.MemoryStream();
            System.Xml.XmlWriterSettings setting = new System.Xml.XmlWriterSettings();
            setting.Encoding = new UTF8Encoding(false);
            setting.Indent = true;
            setting.OmitXmlDeclaration = true;
            using (System.Xml.XmlWriter writer = System.Xml.XmlWriter.Create(stream, setting))
            {
                xs.Serialize(writer, myObject, ns);
            }
            return Encoding.UTF8.GetString(stream.ToArray());
        }
        /// <summary>
        /// 将XML字符串反序列化为对象
        /// </summary>
        /// <typeparam name="T">对象类型</typeparam>
        /// <param name="xml">XML字符</param>
        /// <returns></returns>
        public static T DeserializeToObject<T>(string xml)
        {
            T myObject;
            XmlSerializer serializer = new XmlSerializer(typeof(T));
            StringReader reader = new StringReader(xml);
            myObject = (T)serializer.Deserialize(reader);
            reader.Close();
            return myObject;
        }
        

        /// <summary>
        /// DataModel转换XML
        /// </summary>
        /// <param name="dataModelList">实体对象</param>
        /// <returns></returns>
        public static XmlDocument DataModelByXml(List<DataModel> dataModelList)
        {
            if (dataModelList != null && dataModelList.Any())
            {
                dataModelList = dataModelList.Where(a => a.State != "0").ToList();
            }
            XmlDocument xmlDocument = new XmlDocument();
            DataModel dataModelRoot = dataModelList?.FirstOrDefault(a => a.ParentId == "");
            List<string> xmlrootList = dataModelRoot?.XmlPath.Split('/').ToList();
            string nodename = "";
            if (xmlrootList != null && xmlrootList.Any())
            {
                nodename = xmlrootList[xmlrootList.Count - 1];
                if (nodename == "")
                {
                    nodename = dataModelRoot.XmlPath.Replace("/", "");
                }
            }
            else
            {
                nodename = dataModelRoot?.XmlPath?.Replace("/", "");
            }
            Regex r = new Regex(@"\[[^,，。;；/]*?\]");
          
            MatchCollection mc = r.Matches(nodename);
            string name = "";
            if (mc.Count > 0)
            {
                for (int i = 0; i < mc.Count; i++)
                {
                    name = nodename.Replace(mc[i].Value, "");
                }
            }
            else
            {
                name = nodename;
            }
            XmlElement xmlElementRoot = xmlDocument.CreateElement(name);
            if (dataModelRoot.AttributesList != null)
            {
                foreach (var attitem in dataModelRoot.AttributesList)
                {
                    if (attitem.Name != "id")
                    {
                        if (attitem.sourceList.FirstOrDefault(a => a.IsCheck == "1")!=null)
                        {
                            xmlElementRoot.SetAttribute(attitem.Name, attitem.sourceList.FirstOrDefault(a => a.IsCheck == "1").SaveValue);
                        }
                        
                    }

                }
            }
            xmlElementRoot.SetAttribute("id", dataModelRoot.ID);
            XmlNodeDocDataModel(xmlElementRoot, xmlDocument, dataModelRoot.ID, dataModelList);
            xmlDocument.AppendChild(xmlElementRoot);
            if (xmlDocument != null )
            {
                xmlDocument = EscapeNodeIndexAndBlank(xmlDocument);
            }
            return xmlDocument;
        }

        /// <summary>
        /// DataModel转换XML
        /// </summary>
        /// <param name="dataModelList">实体对象</param>
        /// <returns></returns>
        public static XmlDocument DataModelByXml(List<DataModel> dataModelList,string parentid)
        {
            if (dataModelList.Count > 0)
            {
                dataModelList = dataModelList.Where(a => a.State != "0").ToList();
            }
            XmlDocument xmlDocument = new XmlDocument();
            DataModel dataModelRoot = dataModelList.FirstOrDefault(a => a.ParentId == parentid);
            string[] strlist = dataModelRoot.XmlPath.Split('/');
            string name = "";
            if (strlist.Length>0)
            {
                name = strlist[strlist.Length - 1];
            }
            if (string.IsNullOrEmpty(name))
            {
                name = dataModelRoot.XmlPath.Replace("/", "");
            }
           
            XmlElement xmlElementRoot = xmlDocument.CreateElement(name);
            xmlElementRoot.SetAttribute("id", dataModelRoot.ID);
            XmlNodeDocDataModel(xmlElementRoot, xmlDocument, dataModelRoot.ID, dataModelList);
            xmlDocument.AppendChild(xmlElementRoot);
            if (xmlDocument != null)
            {
                xmlDocument = EscapeNodeIndexAndBlank(xmlDocument);
            }
            return xmlDocument;
        }

        /// <summary>
        /// 父子级别节点添加
        /// </summary>
        /// <param name="xmlElementRoot">父节点</param>
        /// <param name="xmlDocument">数据对象</param>
        /// <param name="parentID">上级ID</param>
        /// <param name="dataModelList">数据源</param>
        private static void XmlNodeDocDataModel(XmlElement xmlElementRoot, XmlDocument xmlDocument, string parentID, List<DataModel> dataModelList)
        {


            List<DataModel> chanNodelModelList = dataModelList.Where(a => a.ParentId == parentID && a.ID != parentID).ToList();
            foreach (DataModel dataModel in chanNodelModelList)
            {
                string nodename = dataModel.XmlPath.Split('/')[dataModel.XmlPath.Split('/').Length - 1];
                if (string.IsNullOrEmpty(nodename))
                {
                    nodename = dataModel.XmlPath.Replace("/", "");
                }
                Regex r = new Regex(@"\[[^,。;；/]*?\]");
                MatchCollection mc = r.Matches(nodename);
                string name = "";
                if (mc.Count > 0)
                {
                    for (int i = 0; i < mc.Count; i++)
                    {
                        name = nodename.Replace(mc[i].Value, "");
                    }
                }
                else
                {
                    name = nodename;
                }
                XmlElement xmlElementNodel = xmlDocument.CreateElement(name);
                xmlElementNodel.SetAttribute("id", dataModel.ID);
                if (dataModel.AttributesList != null)
                {
                    foreach (var attirValue in dataModel.AttributesList)
                    {
                        if (attirValue.sourceList.FirstOrDefault(a => a.IsCheck == "1") != null)
                        {
                            string saveValue = attirValue.sourceList.FirstOrDefault(a => a.IsCheck == "1").SaveValue;
                            if (!string.IsNullOrEmpty(saveValue))
                            {
                                xmlElementNodel.SetAttribute(attirValue.Name, saveValue);
                            }
                        }

                    }
                }
                XmlNodeDocDataModel(xmlElementNodel, xmlDocument, dataModel.ID, dataModelList);
                xmlElementRoot.AppendChild(xmlElementNodel);
            }

        }

        /// <summary>
        /// 节点去重
        /// </summary>
        /// <param name="docxml">内容实体</param>
        /// <returns></returns>
        public static XmlDocument EscapeNodeIndexAndBlank(XmlDocument docxml)
        {
            docxml = EscapeBlank(docxml);
            return docxml;
        }

        public static XmlDocument EscpeNodeBlankPer(XmlDocument xmlDocument) 
        {
            XmlNodeList xmlNodeList= xmlDocument.SelectNodes("//事实要素");
            if (xmlNodeList!=null && xmlNodeList.Count>0)
            {
                for (int i = 0; i < xmlNodeList.Count; i++)
                {
                    XmlNode nodeRoot = xmlNodeList[i];
                    if (nodeRoot.ChildNodes.Count == 1 && nodeRoot.ChildNodes[0].Name == "主张方")
                    {
                        xmlDocument.ChildNodes[0].RemoveChild(nodeRoot);
                    }
                }
                
            }
            return xmlDocument;
        }
        /// <summary>
        /// 去除xml中的空节点
        /// </summary>//*[not(attribute::*) and not (child::*)]
        /// <param name="second">待去除xml</param>
        /// <returns>取出后的结果</returns>
        protected static XmlDocument EscapeBlank(XmlDocument second)
        {
            //XmlNodeList blanks = second.SelectNodes("//*[ not (child::*)]");//取无属性 无子节点的节点

            //while (blanks.Count > 0)
            //{
            //    bool flag = true;

            //    foreach (XmlNode node in blanks)
            //    {
            //        if (node.Attributes["id"] != null && node.Attributes.Count == 1)
            //        {
            //            if (node.ParentNode != null && node.ParentNode.ParentNode != null)
            //            {
            //                node.ParentNode.RemoveChild(node);
            //            }
            //            else
            //            {
            //                flag = false;
            //            }
            //        }
            //        else
            //        {
            //            flag = false; 
            //        }


            //    }
            //    blanks = second.SelectNodes("//*[ not (child::*)]");//递归查询

            //    if (!flag)
            //    {
            //        break;
            //    }

            //}
            //return second;

            XmlNodeList blanks = second.SelectNodes("//descendant-or-self::*[not(attribute::*[name()!='id']) and attribute::id and not(child::*)]");//取无属性 无子节点的节点
            while (blanks.Count > 0)
            {
                bool flag = true;
                foreach (XmlNode node in blanks)
                {
                    if (node.ParentNode.ParentNode != null)
                    {
                        node.ParentNode.RemoveChild(node);
                    }
                    else
                    {
                        flag = false;
                    }
                }
                blanks = second.SelectNodes("//descendant-or-self::*[not(attribute::*[name()!='id']) and attribute::id and not(child::*)]");//递归查询
                if (!flag)
                    break;
            }
            return second;
        }

        public XmlDocument EscapeBlank_new(XmlDocument second)
        {
            XmlNodeList blanks = second.SelectNodes("//*[not(attribute::*) and not (child::*)]");//取无属性 无子节点的节点
            while (blanks.Count > 0)
            {
                bool flag = true;
                foreach (XmlNode node in blanks)
                {
                    if (node.ParentNode.ParentNode != null)
                    {
                        node.ParentNode.RemoveChild(node);
                    }
                    else
                    {
                        flag = false;
                    }
                }
                blanks = second.SelectNodes("//*[not(attribute::*) and not (child::*)]");//递归查询
                if (!flag)
                    break;
            }
            return second;
        }
        /// <summary>
        /// 根据xmlpath条件查询实体信息
        /// </summary>
        /// <param name="dataModelList">实体集合</param>
        /// <param name="parentid">根节点ID</param>
        /// <param name="xmlpath">xml路径</param>
        /// <returns></returns>
        public static List<DataModel> ConditionDataModelList(List<DataModel> dataModelList, string parentid, string xmlpath)
        {
            if (dataModelList.Count==0)
            {
                return null;
            }
            XmlUtilCommon xmlUtilCommon = new XmlUtilCommon();
            XmlDocument xmlDocument = xmlUtilCommon.DataModelByXml(dataModelList, parentid, false);

            XmlNodeList xmlNodeList = xmlDocument.SelectNodes(xmlpath);
            List<DataModel> resultList = new List<DataModel>();
            if (xmlNodeList!=null && xmlNodeList.Count>0)
            {
                foreach (XmlNode xmlNode in xmlNodeList)
                {
                    resultList.Add(dataModelList.FirstOrDefault(a => a.ID == xmlNode.Attributes["id"].Value));
                }
            }
            return resultList;
        }

        /// <summary>
        /// 获取符合xmlpaht条件查询的第一个实体
        /// </summary>
        /// <param name="dataModelList">实体集合</param>
        /// <param name="parentid">根节点ID</param>
        /// <param name="xmlpath">xml路径</param>
        /// <returns></returns>
        public static DataModel ConditionFirstOrDefaultDataModel(List<DataModel> dataModelList, string parentid, string xmlpath)
        {
            XmlUtilCommon xmlUtilCommon = new XmlUtilCommon();
            XmlDocument xmlDocument = xmlUtilCommon.DataModelByXml(dataModelList,parentid,false);
            

            XmlNode xmlNode = xmlDocument.SelectSingleNode(xmlpath);
            DataModel result = new DataModel();
            if (xmlNode != null)
            {
                if(xmlNode.NodeType==XmlNodeType.Attribute)
                {
                    var elementPath = xmlpath.Split('/').ToList();
                    var newPath = xmlpath.Replace(elementPath[elementPath.Count-1], "").TrimEnd('/');
                    XmlNode newNode= xmlDocument.SelectSingleNode(newPath);
                    if (newNode != null)
                    {
                        result = dataModelList.FirstOrDefault(a => a.ID == newNode.Attributes["id"].Value);
                    }
                }
                else if(xmlNode.NodeType == XmlNodeType.Element)
                {
                    result = dataModelList.FirstOrDefault(a => a.ID == xmlNode.Attributes["id"].Value);
                }
                
                return result;
            }
            return null;
        }

        /// <summary>
        /// 人员排序
        /// </summary>
        /// <param name="dataModelList"></param>
        /// <param name="xpath"></param>
        /// <returns></returns>
        public static List<DataModel> GetDataModelOrder(List<DataModel> dataModelList, string xpath)
        {

            if (dataModelList.FirstOrDefault(a => a.XmlPath == xpath) != null)
            {
                List<DataModel> dataModels = dataModelList.Where(a => a.XmlPath == xpath).ToList();
                foreach (DataModel model in dataModels)
                {
                    dataModelList.Remove(model);
                }
                dataModels = dataModels.OrderBy(a => Convert.ToInt32(a.AttributesList.FirstOrDefault(b => b.Name == "诉讼地位").sourceList.FirstOrDefault(c => c.IsCheck == "1").SaveValue)).ToList();
                dataModelList.AddRange(dataModels);
            }
            return dataModelList;
        }

        /// <summary>
        /// 根据xml查询
        /// </summary>
        /// <param name="xmlDocument"></param>
        /// <param name="path"></param>
        /// <returns></returns>
        public static XmlNode SelectXMLPaht(XmlDocument xmlDocument,string path) 
        {
            List<string> pathList = path.Split("/").ToList();
            string elmentpath = "";
            foreach (string xpath in pathList)
            {
                XmlNode xmlNode= xmlDocument.SelectSingleNode(elmentpath + "/" + xpath);
                if (xmlNode==null)
                {
                    XmlNode node =  xmlDocument.SelectSingleNode(elmentpath);
                    XmlElement xe1 = xmlDocument.CreateElement(xpath);
                    node.AppendChild(xe1);
                    xmlNode = xmlDocument.SelectSingleNode(elmentpath + "/" + xpath);

                }
                elmentpath = elmentpath + "/" + xpath;
            }

            return xmlDocument.SelectSingleNode(path);
        }
    }
    public class Class1<T> 
    {
        
        private Func<int, int, List<T>> a;

        public Func<int, int, List<T>> b
        {
            get { return a; }
            set { a = value; }
        }

       
    }
}
